package Or

import (
	"context"
	"fmt"
	"db2s/ETL"
	"db2s/global"
	"db2s/go-log/log"
	"db2s/parDef"
	"db2s/ref"
	"strings"
)

func (pm PartitionMe) PartType(ctx context.Context) (result global.Return, err error) {
	var event = "[PartType]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	var _, table = parDef.GetExecFuncParameterValueBase(ctx)
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		if result, err = parDef.SqlExec(parDef.GetSqlQueryExecFuncParameterValue(ctx, event, partitionTableSysObjectView, getTablePartitionTypeMetaSql, QueryColValManage)); err != nil {
			return
		}
		return parDef.ResultExec(parDef.NewGetExternalExecFuncParameterValue(ctx, event, result, result.Result, table))
	}
}
func (pm PartitionMe) PartSum(ctx context.Context) (result global.Return, err error) {
	var event = "[PartSum]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	var _, table = parDef.GetExecFuncParameterValueBase(ctx)
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		if result, err = parDef.SqlExec(parDef.GetSqlQueryExecFuncParameterValue(ctx, event, tablePartitionSysObjectView, getTablePartitionSumMetaSql, QueryColValManage)); err != nil {
			return
		}
		return parDef.ResultExec(parDef.NewGetExternalExecFuncParameterValue(ctx, event, result, result.Result, table))
	}
}
func (pm PartitionMe) selectFromDual(ctx context.Context, selectBody string) (result []string, err error) {
	var event = "[selectFromDual]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	if strings.Contains(selectBody, "MAXVALUE") || strings.EqualFold(selectBody, "NULL") {
		result = strings.Split(selectBody, ",")
		return
	}
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		var res global.Return
		if res, err = parDef.SqlExec(parDef.GetSubSqlExecFuncParameterValue(ctx, event, ETL.String, dualSysObjectView, func(o, s, t string) string {
			return fmt.Sprintf("select %v from dual", selectBody)
		}, QueryColValManage)); err != nil {
			log.ErrorLog().Error(event, getTableName(parDef.GetExecFuncParameterValueBase(ctx)), fmt.Sprintf(" sql is %v, error is %v.", res.Sql, err))
			return
		}
		for k, v := range strings.Split(res.Result.(string), ETL.DataColumnsSplit) {
			var p string
			if strings.TrimSpace(strings.ReplaceAll(strings.Split(selectBody, ",")[k], "'", "")) == strings.TrimSpace(v) {
				p = strings.Split(selectBody, ",")[k]
			} else {
				p = v
			}
			if n := strings.Index(v, "+0800"); n != -1 {
				p = fmt.Sprintf("'%v'", strings.TrimSpace(v[:n]))
			}
			result = append(result, p)
		}
	}
	return
}
func (pm PartitionMe) getPartRule(ctx context.Context) (result global.Return, err error) {
	var event = "[getPartRule]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		if result, err = parDef.SqlExec(parDef.GetSubSqlExecFuncParameterValue(ctx, event, ETL.SMap, tablePartitionSysObjectView, getTablePartitionRuleMetaSql, QueryColValManage)); err != nil {
			log.ErrorLog().Error(event, getTableName(parDef.GetExecFuncParameterValueBase(ctx)), fmt.Sprintf(" sql is %v, error is %v.", result.Sql, err))
			return
		}
		if result.Result == nil {
			return
		}
		var res []parDef.PartRule
		for _, v := range result.Result.([]map[string]any) {
			vv := mapNullActive(v)
			var rul []string
			if rul, err = pm.selectFromDual(ctx, fmt.Sprintf("%v", vv["rules"])); err != nil {
				err = ref.ErrAddPrintf("getPartRule", err)
				return
			}
			vv["rules"] = strings.Join(rul, ",")
			var rule parDef.PartRule
			if err = ref.MapToStruct(vv, &rule); err != nil {
				err = ref.ErrAddPrintf("getPartRule", err)
				return
			}
			res = append(res, rule)
		}
		result.Result = res
	}
	return
}
func (pm PartitionMe) getSubPartRule(ctx context.Context) (result global.Return, err error) {
	var event = "[getSubPartColumn]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		if result, err = parDef.SqlExec(parDef.GetSubSqlExecFuncParameterValue(ctx, event, ETL.SMap, subPartitionTableSysObjectView, getTableSubPartitionRuleMetaSql, QueryColValManage)); err != nil {
			log.ErrorLog().Error(event, getTableName(parDef.GetExecFuncParameterValueBase(ctx)), fmt.Sprintf(" sql is %v, error is %v.", result.Sql, err))
			return
		}
		if result.Result == nil {
			return
		}
		var res []parDef.PartRule
		for _, v := range result.Result.([]map[string]any) {
			vv := mapNullActive(v)
			if strings.EqualFold(fmt.Sprintf("%v", vv["rules"]), "NULL") {
				vv["rules"] = "''"
			}
			var rule parDef.PartRule
			if err = ref.MapToStruct(vv, &rule); err != nil {
				err = ref.ErrAddPrintf("getSubPartRule", err)
				return
			}
			res = append(res, rule)
		}
		result.Result = res
	}
	return
}

func (pm PartitionMe) getPartMeth(ctx context.Context) (result global.Return, err error) {
	var event = "[getPartMeth]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		var res parDef.PartMeth
		if result, err = parDef.SqlExec(parDef.GetSubSqlExecFuncParameterValue(ctx, event, ETL.Map, partitionTableSysObjectView, getTablePartitionMethMetaSql, QueryColValManage)); err != nil {
			log.ErrorLog().Error(event, getTableName(parDef.GetExecFuncParameterValueBase(ctx)), fmt.Sprintf(" sql is %v, error is %v.", result.Sql, err))
			return
		}
		if result.Result == nil {
			return
		}
		pp := mapNullActive(result.Result.(map[string]any))
		if err = ref.MapToStruct(pp, &res); err != nil {
			err = ref.ErrAddPrintf("getPartMeth", err)
			return
		}
		if strings.EqualFold(fmt.Sprintf("%v", pp["first"]), "NONE") {
			res.First = "NULL"
		}
		if strings.EqualFold(fmt.Sprintf("%v", pp["sub"]), "NONE") {
			res.Sub = "NULL"
		}
		result.Result = res
	}
	return
}
func (pm PartitionMe) getFirstPartColumn(ctx context.Context) (result global.Return, err error) {
	var event = "[GetFirstPartName]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		if result, err = parDef.SqlExec(parDef.GetSubSqlExecFuncParameterValue(ctx, event, ETL.StringGarth, partitionColumnSysObjectView, getTablePartitionColMetaSql, QueryColValManage)); err != nil {
			log.ErrorLog().Error(event, getTableName(parDef.GetExecFuncParameterValueBase(ctx)), fmt.Sprintf(" sql is %v, error is %v.", result.Sql, err))
			return
		}
	}
	return
}
func (pm PartitionMe) getSubPartColumn(ctx context.Context) (result global.Return, err error) {
	var event = "[getSubPartColumn]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		if result, err = parDef.SqlExec(parDef.GetSubSqlExecFuncParameterValue(ctx, event, ETL.StringGarth, partitionSubColumnSysObjectView, getTableSubPartitionColMetaSql, QueryColValManage)); err != nil {
			log.ErrorLog().Error(event, getTableName(parDef.GetExecFuncParameterValueBase(ctx)), fmt.Sprintf(" sql is %v, error is %v.", result.Sql, err))
			return
		}
	}
	return
}

func (pm PartitionMe) newPartMetaBaseInit(ctx context.Context) (result parDef.PartMetaData, err error) {
	var res global.Return
	if res, err = pm.getPartRule(ctx); err != nil {
		err = ref.ErrAddPrintf("newPartMetaBaseInit", err)
		return
	} else {
		switch res.Result.(type) {
		case []parDef.PartRule:
			result.RuleDesc = res.Result.([]parDef.PartRule)
		}
	}
	if res, err = pm.getPartMeth(ctx); err != nil {
		err = ref.ErrAddPrintf("newPartMetaBaseInit", err)
		return
	} else {
		switch res.Result.(type) {
		case parDef.PartMeth:
			result.Meth = res.Result.(parDef.PartMeth)
		}
	}
	if res, err = pm.getFirstPartColumn(ctx); err != nil {
		err = ref.ErrAddPrintf("newPartMetaBaseInit", err)
		return
	} else {
		switch res.Result.(type) {
		case []string:
			result.PartCol = res.Result.([]string)
		}
	}
	if res, err = pm.getSubPartRule(ctx); err != nil {
		err = ref.ErrAddPrintf("newPartMetaBaseInit", err)
		return
	} else {
		switch res.Result.(type) {
		case []parDef.PartRule:
			result.SubPartDesc = res.Result.([]parDef.PartRule)
		}
	}
	if res, err = pm.getSubPartColumn(ctx); err != nil {
		err = ref.ErrAddPrintf("newPartMetaBaseInit", err)
		return
	} else {
		switch res.Result.(type) {
		case []string:
			result.SubPartCol = res.Result.([]string)
		}
	}
	return
}
func (pm PartitionMe) PartMeta(ctx context.Context) (result global.Return, err error) {
	var baseResult parDef.PartMetaData
	var partName []string
	if baseResult, err = pm.newPartMetaBaseInit(ctx); err != nil {
		err = ref.ErrAddPrintf("PartMeta", err)
		return
	}
	for _, v := range baseResult.RuleDesc {
		partName = append(partName, v.Name)
	}
	baseResult.PartName = partName
	result.Result = baseResult
	return
}

func (pm PartitionMe) NameToRuleClip(ctx context.Context) (result global.Return, err error) {
	return
}
